4.1 算数运算符
一元运算符
运算符 | 说明 | 备注 | |
---|---|---|---|
+ | 一元正号运算符 | 在经典c 中不存在这种运算符,它主要用于强调某数值常量是正数 |
|
- | 一元负号号运算符 |
二元运算符
注意:
- 除
%
外,二元运算符允许操作数既可以是整数也可以是浮点数,或者是两者混合int
类型的操作数和float
型操作数混合在一起时,运算结果为float
型- 当
/
和%
用于负操作数时,其结果与具体实现有关由实现定义(implementtion-defined):软件在特定的平台上编译、链接和执行,行为可能会稍有差异。这是c语言为了和硬件平台匹配追求高效率的结果。
运算符 | 说明 | 备注 |
---|---|---|
+ | 加法运算符 | |
- | 减法运算符 | |
* | 乘法运算符 | |
/ | 除法运算符 | 当两个操作数都是整数时,运算结果会向下取整 |
% | 取余运算符 | 操作数要求都是整数,否则无法编译通过 |
4.1.1 运算符的优先级与结合性
注意:很少有程序员会费心记住优先级和结合性规则,而是在需要时参考运算符表或添加足够多的
()
。
运算符优先级:
优先级 | 运算符 |
---|---|
最高优先级 | +(负) -(正) * / % |
最低优先级 | +(加) -(减) |
结合性:
- 一元运算符都是右结合
(right assoiative)
的,即从右向左结合
1 | -+i;//-(+i) |
- 二元运算符都是左结合
(left assoiative)
的,即从左向右结合
1 | i-j-k;//(i-j)-k |
4.1.2 程序:计算通用产品代码的校验位
1 | /** |
1 | $ ./upc |
4.2 赋值运算符
注意:c语言的
=
不是语句
,而是运算符
。赋值表达式v=e
的结果是v的值。
4.2.1 简单赋值
语法:
v=e
,e
可以是常量、变量或表达式。
副作用:简单赋值运算符是已知的第一个有副作用的运算符,因为它会改变操作数的值。
1 i = j = k = 0;//i = (j = k = 0)
4.2.2 左值
定义:
Q&A
左值表示存储在计算机内存中的对象,而不是常量和计算结果。例如变量。
注意:赋值运算符要求左边的操作数必须是左值。
4.2.3 复合赋值
用途:简化利用变量原有值计算出新值,并重新赋值给这个变量的操作。
列举:共10种
+= | -= | *= | /= | %= |
---|---|---|---|---|
注意:
v += e
并不完全等同于v = v + e
(优先级问题)
4.3 自增运算符和自减运算符
和
i+=1
或i-=1
的区别:
++
和--
既可以是前缀运算符,也可以是后缀运算符- 和赋值运算符一样,
++
和--
也有副作用:它会改变操作数的值
前缀使用和后缀使用的区别:
方式 | 语法 | 执行时机 | 优先级 | 备注 |
---|---|---|---|---|
前缀方式 | ++i 或--i |
立即执行 | 和一元正负号 优先级相同,右结合方式 |
|
后缀方式 | i++ 或++i |
稍后再执行 | 高于一元正负号 ,左结合方式 |
Q&A 没有给出明确的时间,当会是下一条语句执行之前 |
4.4 表达式求值
4.4.1 部分c语言运算符表
4.4.2 为表达式添加圆括号
过程:检查表达式,找到最高优先级的运算符后,用圆括号把运算符合相应的操作数括起来,圆括号的内容将被看成一个单独的操作数。然后重复此类操作指导表达式被完全加上圆括号。
1 | s=>start: start |
4.4.3 子表达式的求值顺序
注意:c语言并没有定义子表达式的求值顺序(
&&
||
条件运算符
逗号运算符
除外)
1 | a = 5; |
建议:不在表达式种使用赋值运算符,而是采用一串分离的赋值表达式。
4.5 表达式语句
表达式转换为语句:任何表达式都可以通过添加分号转换为语句。
注意:除非表达式有副作用,否则将表达式用作语句并没有任何意义。
1 | int i = 1; |